﻿Imports System
Imports System.CodeDom
Imports System.Collections.Generic
Imports System.Diagnostics.CodeAnalysis
Imports System.Globalization
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.Activities.Rules
    Friend MustInherit Class ArithmeticLiteral
        ' Methods
        Protected Sub New()
        End Sub

        Friend Overridable Function Add() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.Add, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Boolean) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Char) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As String) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Add, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function Add(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.TypeName, CodeBinaryOperatorType.Add, Me.TypeName }), v.m_type, CodeBinaryOperatorType.Add, Me.m_type)
        End Function

        Friend Overridable Function BitAnd() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As Boolean) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitAnd(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.m_type, CodeBinaryOperatorType.BitwiseAnd, Me.TypeName }), v.m_type, CodeBinaryOperatorType.BitwiseAnd, Me.m_type)
        End Function

        Friend Overridable Function BitOr() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As Boolean) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.GetType, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Friend Overridable Function BitOr(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.TypeName, CodeBinaryOperatorType.BitwiseOr, Me.TypeName }), v.m_type, CodeBinaryOperatorType.BitwiseOr, Me.m_type)
        End Function

        Private Shared Function CreateSupportedTypesDictionary() As Dictionary([Of] Type, TypeFlags)
            Dim dictionary As New Dictionary([Of] Type, TypeFlags)(&H1A)
            dictionary.Add(GetType(Byte), TypeFlags.UInt16)
            dictionary.Add(GetType(Nullable([Of] Byte)), (TypeFlags.Nullable Or TypeFlags.UInt16))
            dictionary.Add(GetType([SByte]), TypeFlags.Int32)
            dictionary.Add(GetType(Nullable([Of] [SByte])), (TypeFlags.Nullable Or TypeFlags.Int32))
            dictionary.Add(GetType(Char), TypeFlags.UInt16)
            dictionary.Add(GetType(Nullable([Of] Char)), (TypeFlags.Nullable Or TypeFlags.UInt16))
            dictionary.Add(GetType(Short), TypeFlags.Int32)
            dictionary.Add(GetType(Nullable([Of] Short)), (TypeFlags.Nullable Or TypeFlags.Int32))
            dictionary.Add(GetType(Integer), TypeFlags.Int32)
            dictionary.Add(GetType(Nullable([Of] Integer)), (TypeFlags.Nullable Or TypeFlags.Int32))
            dictionary.Add(GetType(Long), TypeFlags.Int64)
            dictionary.Add(GetType(Nullable([Of] Long)), (TypeFlags.Nullable Or TypeFlags.Int64))
            dictionary.Add(GetType(UInt16), TypeFlags.UInt16)
            dictionary.Add(GetType(Nullable([Of] UInt16)), (TypeFlags.Nullable Or TypeFlags.UInt16))
            dictionary.Add(GetType(UInt32), TypeFlags.UInt32)
            dictionary.Add(GetType(Nullable([Of] UInt32)), (TypeFlags.Nullable Or TypeFlags.UInt32))
            dictionary.Add(GetType(UInt64), TypeFlags.UInt64)
            dictionary.Add(GetType(Nullable([Of] UInt64)), (TypeFlags.Nullable Or TypeFlags.UInt64))
            dictionary.Add(GetType(Single), TypeFlags.Single)
            dictionary.Add(GetType(Nullable([Of] Single)), (TypeFlags.Nullable Or TypeFlags.Single))
            dictionary.Add(GetType(Double), TypeFlags.Double)
            dictionary.Add(GetType(Nullable([Of] Double)), (TypeFlags.Nullable Or TypeFlags.Double))
            dictionary.Add(GetType(Decimal), TypeFlags.Decimal)
            dictionary.Add(GetType(Nullable([Of] Decimal)), (TypeFlags.Nullable Or TypeFlags.Decimal))
            dictionary.Add(GetType(Boolean), TypeFlags.Boolean)
            dictionary.Add(GetType(Nullable([Of] Boolean)), (TypeFlags.Nullable Or TypeFlags.Boolean))
            dictionary.Add(GetType(String), TypeFlags.String)
            Return dictionary
        End Function

        Private Shared Function CreateTypesDictionary() As Dictionary([Of] Type, LiteralMaker)
            Dim dictionary As New Dictionary([Of] Type, LiteralMaker)(&H10)
            dictionary.Add(GetType(Byte), New LiteralMaker(AddressOf ArithmeticLiteral.MakeByte))
            dictionary.Add(GetType([SByte]), New LiteralMaker(AddressOf ArithmeticLiteral.MakeSByte))
            dictionary.Add(GetType(Char), New LiteralMaker(AddressOf ArithmeticLiteral.MakeChar))
            dictionary.Add(GetType(Short), New LiteralMaker(AddressOf ArithmeticLiteral.MakeShort))
            dictionary.Add(GetType(Integer), New LiteralMaker(AddressOf ArithmeticLiteral.MakeInt))
            dictionary.Add(GetType(Long), New LiteralMaker(AddressOf ArithmeticLiteral.MakeLong))
            dictionary.Add(GetType(UInt16), New LiteralMaker(AddressOf ArithmeticLiteral.MakeUShort))
            dictionary.Add(GetType(UInt32), New LiteralMaker(AddressOf ArithmeticLiteral.MakeUInt))
            dictionary.Add(GetType(UInt64), New LiteralMaker(AddressOf ArithmeticLiteral.MakeULong))
            dictionary.Add(GetType(Single), New LiteralMaker(AddressOf ArithmeticLiteral.MakeFloat))
            dictionary.Add(GetType(Double), New LiteralMaker(AddressOf ArithmeticLiteral.MakeDouble))
            dictionary.Add(GetType(Decimal), New LiteralMaker(AddressOf ArithmeticLiteral.MakeDecimal))
            dictionary.Add(GetType(Boolean), New LiteralMaker(AddressOf ArithmeticLiteral.MakeBoolean))
            dictionary.Add(GetType(String), New LiteralMaker(AddressOf ArithmeticLiteral.MakeString))
            dictionary.Add(GetType(Nullable([Of] Byte)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeByte))
            dictionary.Add(GetType(Nullable([Of] [SByte])), New LiteralMaker(AddressOf ArithmeticLiteral.MakeSByte))
            dictionary.Add(GetType(Nullable([Of] Char)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeChar))
            dictionary.Add(GetType(Nullable([Of] Short)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeShort))
            dictionary.Add(GetType(Nullable([Of] Integer)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeInt))
            dictionary.Add(GetType(Nullable([Of] Long)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeLong))
            dictionary.Add(GetType(Nullable([Of] UInt16)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeUShort))
            dictionary.Add(GetType(Nullable([Of] UInt32)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeUInt))
            dictionary.Add(GetType(Nullable([Of] UInt64)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeULong))
            dictionary.Add(GetType(Nullable([Of] Single)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeFloat))
            dictionary.Add(GetType(Nullable([Of] Double)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeDouble))
            dictionary.Add(GetType(Nullable([Of] Decimal)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeDecimal))
            dictionary.Add(GetType(Nullable([Of] Boolean)), New LiteralMaker(AddressOf ArithmeticLiteral.MakeBoolean))
            Return dictionary
        End Function

        Friend Overridable Function Divide() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.Divide, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Divide, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Friend Overridable Function Divide(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.TypeName, CodeBinaryOperatorType.Divide, Me.TypeName }), v.m_type, CodeBinaryOperatorType.Divide, Me.m_type)
        End Function

        Private Shared Function MakeBoolean(ByVal literalValue As Object) As ArithmeticLiteral
            Return New BooleanArithmeticLiteral(CBool(literalValue))
        End Function

        Private Shared Function MakeByte(ByVal literalValue As Object) As ArithmeticLiteral
            Return New UShortArithmeticLiteral(CByte(literalValue))
        End Function

        Private Shared Function MakeChar(ByVal literalValue As Object) As ArithmeticLiteral
            Return New CharArithmeticLiteral(DirectCast(literalValue, Char))
        End Function

        Private Shared Function MakeDecimal(ByVal literalValue As Object) As ArithmeticLiteral
            Return New DecimalArithmeticLiteral(CDec(literalValue))
        End Function

        Private Shared Function MakeDouble(ByVal literalValue As Object) As ArithmeticLiteral
            Return New DoubleArithmeticLiteral(CDbl(literalValue))
        End Function

        Private Shared Function MakeFloat(ByVal literalValue As Object) As ArithmeticLiteral
            Return New FloatArithmeticLiteral(CSng(literalValue))
        End Function

        Private Shared Function MakeInt(ByVal literalValue As Object) As ArithmeticLiteral
            Return New IntArithmeticLiteral(CInt(literalValue))
        End Function

        Friend Shared Function MakeLiteral(ByVal literalType As Type, ByVal literalValue As Object) As ArithmeticLiteral
            Dim maker As LiteralMaker
            If (literalValue Is Nothing) Then
                Return New NullArithmeticLiteral(literalType)
            End If
            If Not ArithmeticLiteral.types.TryGetValue(literalType, maker) Then
                Return Nothing
            End If
            Return maker.Invoke(literalValue)
        End Function

        Private Shared Function MakeLong(ByVal literalValue As Object) As ArithmeticLiteral
            Return New LongArithmeticLiteral(CLng(literalValue))
        End Function

        Private Shared Function MakeSByte(ByVal literalValue As Object) As ArithmeticLiteral
            Return New IntArithmeticLiteral([CSByte](literalValue))
        End Function

        Private Shared Function MakeShort(ByVal literalValue As Object) As ArithmeticLiteral
            Return New IntArithmeticLiteral(CShort(literalValue))
        End Function

        Private Shared Function MakeString(ByVal literalValue As Object) As ArithmeticLiteral
            Return New StringArithmeticLiteral(literalValue.ToString)
        End Function

        Private Shared Function MakeUInt(ByVal literalValue As Object) As ArithmeticLiteral
            Return New UIntArithmeticLiteral(DirectCast(literalValue, UInt32))
        End Function

        Private Shared Function MakeULong(ByVal literalValue As Object) As ArithmeticLiteral
            Return New ULongArithmeticLiteral([CULng](literalValue))
        End Function

        Private Shared Function MakeUShort(ByVal literalValue As Object) As ArithmeticLiteral
            Return New UShortArithmeticLiteral([CUShort](literalValue))
        End Function

        Friend Overridable Function Modulus() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.Modulus, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Modulus(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.m_type, CodeBinaryOperatorType.Modulus, Me.TypeName }), v.m_type, CodeBinaryOperatorType.Modulus, Me.m_type)
        End Function

        Friend Overridable Function Multiply() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.Multiply, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        Friend Overridable Function Multiply(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.TypeName, CodeBinaryOperatorType.Multiply, Me.TypeName }), v.m_type, CodeBinaryOperatorType.Multiply, Me.m_type)
        End Function

        <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
        Private Shared Function ResultType(ByVal operation As CodeBinaryOperatorType, ByVal lhsType As TypeFlags, ByVal rhsType As TypeFlags) As Type
            Dim flags As TypeFlags = (lhsType Or rhsType)
            Dim flag As Boolean = ((flags And TypeFlags.Nullable) = TypeFlags.Nullable)
            If flag Then
                flags = (flags Xor TypeFlags.Nullable)
            End If
            Select Case operation
                Case CodeBinaryOperatorType.Add
                    If ((lhsType <> TypeFlags.String) AndAlso (rhsType <> TypeFlags.String)) Then
                        Exit Select
                    End If
                    Return GetType(String)
                Case CodeBinaryOperatorType.Subtract, CodeBinaryOperatorType.Multiply, CodeBinaryOperatorType.Divide, CodeBinaryOperatorType.Modulus
                    Exit Select
                Case CodeBinaryOperatorType.BitwiseOr, CodeBinaryOperatorType.BitwiseAnd
                    Select Case flags
                        Case TypeFlags.UInt16, TypeFlags.Int32, (TypeFlags.Int32 Or TypeFlags.UInt16)
                            If Not flag Then
                                Return GetType(Integer)
                            End If
                            Return GetType(Nullable([Of] Integer))
                        Case TypeFlags.UInt32, (TypeFlags.UInt32 Or TypeFlags.UInt16)
                            If Not flag Then
                                Return GetType(UInt32)
                            End If
                            Return GetType(Nullable([Of] UInt32))
                        Case (TypeFlags.UInt32 Or TypeFlags.Int32), TypeFlags.Int64, (TypeFlags.Int64 Or TypeFlags.UInt16), (TypeFlags.Int64 Or TypeFlags.Int32), (TypeFlags.Int64 Or TypeFlags.UInt32)
                            If Not flag Then
                                Return GetType(Long)
                            End If
                            Return GetType(Nullable([Of] Long))
                        Case (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Int64 Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Int64 Or (TypeFlags.UInt32 Or TypeFlags.UInt16)), (TypeFlags.Int64 Or (TypeFlags.UInt32 Or TypeFlags.Int32)), (TypeFlags.Int64 Or (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16))), (TypeFlags.UInt64 Or TypeFlags.Int32), (TypeFlags.UInt64 Or (TypeFlags.Int32 Or TypeFlags.UInt16))
                            goto Label_032A
                        Case TypeFlags.UInt64, (TypeFlags.UInt64 Or TypeFlags.UInt16), (TypeFlags.UInt64 Or TypeFlags.UInt32)
                            If Not flag Then
                                Return GetType(UInt64)
                            End If
                            Return GetType(Nullable([Of] UInt64))
                        Case TypeFlags.Boolean
                            If Not flag Then
                                Return GetType(Boolean)
                            End If
                            Return GetType(Nullable([Of] Boolean))
                    End Select
                    goto Label_032A
                Case Else
                    goto Label_032A
            End Select
            Select Case flags
                Case TypeFlags.Double, (TypeFlags.Double Or TypeFlags.UInt16), (TypeFlags.Double Or TypeFlags.Int32), (TypeFlags.Double Or TypeFlags.UInt32), (TypeFlags.Double Or TypeFlags.Int64), (TypeFlags.Double Or TypeFlags.UInt64), (TypeFlags.Double Or TypeFlags.Single)
                    If Not flag Then
                        Return GetType(Double)
                    End If
                    Return GetType(Nullable([Of] Double))
                Case (TypeFlags.Double Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Double Or (TypeFlags.UInt32 Or TypeFlags.UInt16)), (TypeFlags.Double Or (TypeFlags.UInt32 Or TypeFlags.Int32)), (TypeFlags.Double Or (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16))), (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Int64 Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Int64 Or (TypeFlags.UInt32 Or TypeFlags.UInt16)), (TypeFlags.Int64 Or (TypeFlags.UInt32 Or TypeFlags.Int32)), (TypeFlags.Int64 Or (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16))), (TypeFlags.UInt64 Or TypeFlags.Int32), (TypeFlags.UInt64 Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Single Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Single Or (TypeFlags.UInt32 Or TypeFlags.UInt16)), (TypeFlags.Single Or (TypeFlags.UInt32 Or TypeFlags.Int32)), (TypeFlags.Single Or (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16))), (TypeFlags.Decimal Or (TypeFlags.Int32 Or TypeFlags.UInt16)), (TypeFlags.Decimal Or (TypeFlags.UInt32 Or TypeFlags.UInt16)), (TypeFlags.Decimal Or (TypeFlags.UInt32 Or TypeFlags.Int32)), (TypeFlags.Decimal Or (TypeFlags.UInt32 Or (TypeFlags.Int32 Or TypeFlags.UInt16)))
                    goto Label_032A
                Case (TypeFlags.Single Or TypeFlags.UInt64), TypeFlags.Single, (TypeFlags.Single Or TypeFlags.UInt16), (TypeFlags.Single Or TypeFlags.Int32), (TypeFlags.Single Or TypeFlags.UInt32), (TypeFlags.Single Or TypeFlags.Int64)
                    If Not flag Then
                        Return GetType(Single)
                    End If
                    Return GetType(Nullable([Of] Single))
                Case TypeFlags.UInt16, TypeFlags.Int32, (TypeFlags.Int32 Or TypeFlags.UInt16)
                    If flag Then
                        Return GetType(Nullable([Of] Integer))
                    End If
                    Return GetType(Integer)
                Case TypeFlags.UInt32, (TypeFlags.UInt32 Or TypeFlags.UInt16)
                    If flag Then
                        Return GetType(Nullable([Of] UInt32))
                    End If
                    Return GetType(UInt32)
                Case (TypeFlags.UInt32 Or TypeFlags.Int32), TypeFlags.Int64, (TypeFlags.Int64 Or TypeFlags.UInt16), (TypeFlags.Int64 Or TypeFlags.Int32), (TypeFlags.Int64 Or TypeFlags.UInt32)
                    If flag Then
                        Return GetType(Nullable([Of] Long))
                    End If
                    Return GetType(Long)
                Case TypeFlags.UInt64, (TypeFlags.UInt64 Or TypeFlags.UInt16), (TypeFlags.UInt64 Or TypeFlags.UInt32)
                    If flag Then
                        Return GetType(Nullable([Of] UInt64))
                    End If
                    Return GetType(UInt64)
                Case TypeFlags.Decimal, (TypeFlags.Decimal Or TypeFlags.UInt16), (TypeFlags.Decimal Or TypeFlags.Int32), (TypeFlags.Decimal Or TypeFlags.UInt32), (TypeFlags.Decimal Or TypeFlags.Int64), (TypeFlags.Decimal Or TypeFlags.UInt64)
                    If Not flag Then
                        Return GetType(Decimal)
                    End If
                    Return GetType(Nullable([Of] Decimal))
            End Select
        Label_032A:
            Return Nothing
        End Function

        Friend Shared Function ResultType(ByVal operation As CodeBinaryOperatorType, ByVal lhs As Type, ByVal lhsExpression As CodeExpression, ByVal rhs As Type, ByVal rhsExpression As CodeExpression, ByVal validator As RuleValidation, <Out> ByRef [error] As ValidationError) As RuleBinaryExpressionInfo
            Dim flags As TypeFlags
            Dim flags2 As TypeFlags
            If (ArithmeticLiteral.supportedTypes.TryGetValue(lhs, flags) AndAlso ArithmeticLiteral.supportedTypes.TryGetValue(rhs, flags2)) Then
                Dim resultType As Type = ArithmeticLiteral.ResultType(operation, flags, flags2)
                If (Not resultType Is Nothing) Then
                    [error] = Nothing
                    Return New RuleBinaryExpressionInfo(lhs, rhs, resultType)
                End If
                Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.ArithOpBadTypes, New Object() { operation.ToString, If((lhs Is GetType(NullLiteral)), Messages.NullValue, RuleDecompiler.DecompileType(lhs)), If((rhs Is GetType(NullLiteral)), Messages.NullValue, RuleDecompiler.DecompileType(rhs)) })
                [error] = New ValidationError(errorText, &H545)
                Return Nothing
            End If
            Dim mi As MethodInfo = Literal.MapOperatorToMethod(operation, lhs, lhsExpression, rhs, rhsExpression, validator, [error])
            If (Not mi Is Nothing) Then
                Return New RuleBinaryExpressionInfo(lhs, rhs, mi)
            End If
            Return Nothing
        End Function

        Friend Overridable Function Subtract() As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { Messages.NullValue, CodeBinaryOperatorType.Subtract, Me.TypeName }), GetType(Void), CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As Decimal) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As Double) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As Integer) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As Long) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As Single) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As UInt16) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As UInt32) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As UInt64) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.GetType, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.GetType, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function

        Friend Overridable Function Subtract(ByVal v As ArithmeticLiteral) As Object
            Throw New RuleEvaluationIncompatibleTypesException(String.Format(CultureInfo.CurrentCulture, Messages.IncompatibleArithmeticTypes, New Object() { v.TypeName, CodeBinaryOperatorType.Subtract, Me.TypeName }), v.m_type, CodeBinaryOperatorType.Subtract, Me.m_type)
        End Function


        ' Properties
        Protected Overridable ReadOnly Property TypeName As String
            Get
                Return Me.m_type.FullName
            End Get
        End Property

        Friend MustOverride ReadOnly Property Value As Object


        ' Fields
        Protected Friend m_type As Type
        Private Shared supportedTypes As Dictionary([Of] Type, TypeFlags) = ArithmeticLiteral.CreateSupportedTypesDictionary
        Private Shared types As Dictionary([Of] Type, LiteralMaker) = ArithmeticLiteral.CreateTypesDictionary

        ' Nested Types
        Private Delegate Function LiteralMaker(ByVal literalValue As Object) As ArithmeticLiteral

        <Flags> _
        Private Enum TypeFlags
            ' Fields
            [Boolean] = &H100
            [Decimal] = &H80
            [Double] = &H40
            Int32 = 2
            Int64 = 8
            Nullable = &H10000
            [Single] = &H20
            [String] = &H800
            UInt16 = 1
            UInt32 = 4
            UInt64 = &H10
        End Enum
    End Class
End Namespace

